#include "cjthread.h"
#include <thread>       // std::jthread和std::thread都在这个头文件中
#include <stop_token>   // 包含stop_source/stop_token（C++20）
#include <memory>
#include <cassert>
#include <atomic>

// 线程上下文：存储线程函数、用户数据和停止源
struct ThreadContext {
    CThreadFunc func;               // C线程函数
    void* user_data;                // 用户数据
    std::stop_source stop_src;      // 停止源（C++20）

    ThreadContext(CThreadFunc f, void* data) 
        : func(f), user_data(data) {}
};

// 不透明结构体的实际实现
struct CThread {
    std::jthread jt;                // 内部使用std::jthread
    std::shared_ptr<ThreadContext> ctx;  // 线程上下文

    CThread(std::jthread&& thread, std::shared_ptr<ThreadContext> context)
        : jt(std::move(thread)), ctx(std::move(context)) {}
};

// 停止检查回调（供C线程函数使用）
static bool is_stopped_callback(void* ctx_ptr) {
    auto* ctx = static_cast<ThreadContext*>(ctx_ptr);
    return ctx->stop_src.stop_requested();
}

// 线程入口函数（C++到C的适配层）
static void thread_entry(std::shared_ptr<ThreadContext> ctx) {
    assert(ctx && ctx->func);
    // 调用C线程函数，传递停止检查回调
    ctx->func(ctx->user_data, is_stopped_callback);
}

// 创建线程
extern "C" CThread* cjthread_create(CThreadFunc func, void* user_data) {
    if (!func) return nullptr;

    // 创建线程上下文
    auto ctx = std::make_shared<ThreadContext>(func, user_data);
    
    // 创建jthread，绑定入口函数和上下文
    // 注意：std::jthread在C++20中位于<thread>头文件
    std::jthread jt(&thread_entry, ctx);
    if (!jt.joinable()) return nullptr;

    // 包装为CThread对象返回
    return new CThread(std::move(jt), ctx);
}

// 销毁线程（自动join）
extern "C" void cjthread_destroy(CThread* thread) {
    if (thread) {
        // std::jthread析构时会自动join，无需手动操作
        delete thread;
    }
}

// 请求线程停止
extern "C" void cjthread_request_stop(CThread* thread) {
    if (thread && thread->ctx) {
        // 触发停止信号
        thread->ctx->stop_src.request_stop();
    }
}

// 获取线程ID
extern "C" uint64_t cjthread_get_id(const CThread* thread) {
    if (!thread) return 0;
    
    // 将std::thread::id转换为uint64_t（简化实现）
    std::thread::id id = thread->jt.get_id();
    return *reinterpret_cast<const uint64_t*>(&id);
}

// 检查线程是否可join
extern "C" bool cjthread_joinable(const CThread* thread) {
    return thread ? thread->jt.joinable() : false;
}

// 手动join线程
extern "C" void cjthread_join(CThread* thread) {
    if (thread && thread->jt.joinable()) {
        thread->jt.join();
    }
}